#include <qlistwidget.h>
#include <qlayout.h>
#include <qevent.h>
#include <qdebug.h>

#include "QyTabNavigator.h"

QyTabNavigator::QyTabNavigator( QWidget * parent ) : QFrame(parent) {

	p_keepWindow = false;

	QHBoxLayout * lo = new QHBoxLayout(this);
	p_sectionList = new QListWidget(this);
	p_itemList = new QListWidget(this);

	lo->setMargin(2);
	lo->setSpacing(2);
	lo->addWidget(p_sectionList);
	lo->addWidget(p_itemList);
	p_sectionList->setSortingEnabled(false);
	p_sectionList->setFocusProxy(this);
	p_itemList->setSortingEnabled(false);
	p_itemList->setFocusProxy(this);

	setWindowFlags(Qt::Popup);
	setFrameShape(QFrame::Box);

	connect( p_sectionList, SIGNAL( itemActivated(QListWidgetItem*) ),
		this, SLOT( sectionActivated(QListWidgetItem*) ) );
	connect( p_itemList, SIGNAL( itemPressed(QListWidgetItem*) ),
		this, SLOT( itemActivated(QListWidgetItem*) ) );

}

QListWidgetItem * QyTabNavigator::selectedItem() const {

	QList<QListWidgetItem*> items = p_itemList->selectedItems();

	if ( items.isEmpty() )
		return 0;

	return items.first();
}

QListWidgetItem * QyTabNavigator::selectedSectionItem() const {

	QList<QListWidgetItem*> items = p_sectionList->selectedItems();

	if ( items.isEmpty() )
		return 0;

	return items.first();
}

int QyTabNavigator::itemIndex( QListWidgetItem * item ) const {

	if (!item)
		return -1;

	int i, count = p_itemList->count();

	for ( i=0; i<count; i++ ) {

		if ( item == p_itemList->item(i) )
			return i;

	}

	return -1;
}

int QyTabNavigator::selectedItemIndex() const {

	return itemIndex( selectedItem() );
}

QString QyTabNavigator::selectedSection() const {

	if ( QListWidgetItem * sectionItem = selectedSectionItem() )
		return sectionItem->text();

	return QString();
}

void QyTabNavigator::addSection( const QString & name, const QStringList & items,
	int defaultIndex )
{

	p_sections[name] = QySection( items, defaultIndex );
	p_sectionList->addItem(name);
	updateList();

}

void QyTabNavigator::clear() {

	p_sectionList->clear();
	p_itemList->clear();
	p_sections.clear();

}

void QyTabNavigator::setCurrentSection( const QString & name ) {

	QList<QListWidgetItem*> items = p_sectionList->findItems( name, Qt::MatchFixedString );

	if ( items.isEmpty() )
		return;

	QListWidgetItem * item = items.first();

	item->setSelected(true);
	p_sectionList->setCurrentItem(item);
	updateList();

}

void QyTabNavigator::setCurrentItem( const QString & section, int index ) {

	qDebug() << "setCurrentItem" << section << index;

	if ( selectedSection() != section ) {

		QList<QListWidgetItem*> items = p_sectionList->findItems( section, Qt::MatchFixedString );

		if ( items.isEmpty() )
			return;

		QListWidgetItem * item = items.first();

		item->setSelected(true);
		p_sectionList->setCurrentItem(item);

		p_itemList->clear();
		p_itemList->addItems( p_sections[ item->text() ].items );

	}

	if ( index >= 0 && index < p_itemList->count() ) {

		p_itemList->item(index)->setSelected(true);
		p_itemList->setCurrentRow(index);

	}

}

void QyTabNavigator::sectionActivated( QListWidgetItem * item ) {

	if (!item)
		return;

	QySection & section = p_sections[ item->text() ];

	p_itemList->clear();
	p_itemList->addItems( section.items );

	if ( section.index >=0 && section.index < p_itemList->count() ) {

		if ( QListWidgetItem * defaultItem = p_itemList->item(section.index) ) {

			QFont font( defaultItem->font() );

			font.setBold(true);
			defaultItem->setFont(font);
			defaultItem->setSelected(true);
			p_itemList->setCurrentItem(defaultItem);

		}

	}

	if ( p_itemList->count() && selectedItemIndex() < 0 ) {

		p_itemList->item(0)->setSelected(true);
		p_itemList->setCurrentRow(0);

	}

}

void QyTabNavigator::itemActivated( QListWidgetItem * item ) {

	Q_UNUSED(item);

	emit_itemChanged( selectedSection(), selectedItemIndex() );

	close();

}

void QyTabNavigator::updateList() {

	if ( QListWidgetItem * item = selectedSectionItem() )
		sectionActivated(item);
	else if ( p_sectionList->count() ) {

		p_sectionList->item(0)->setSelected(true);
		p_sectionList->setCurrentRow(0);

		sectionActivated( p_sectionList->item(0) );

	}

}

void QyTabNavigator::keyPressEvent( QKeyEvent * event ) {

	if ( event->key() == Qt::Key_Up && event->modifiers() == Qt::ControlModifier ) {

		int index = p_sectionList->currentRow() - 1;

		if ( index < 0 )
			index = p_sectionList->count() - 1;

		if ( QListWidgetItem * item = p_sectionList->item(index) )
			setCurrentSection( item->text() );

	} else if ( event->key() == Qt::Key_Down && event->modifiers() == Qt::ControlModifier ) {

		int index = p_sectionList->currentRow() + 1;

		if ( index >= p_sectionList->count() )
			index = 0;

		if ( QListWidgetItem * item = p_sectionList->item(index) )
			setCurrentSection( item->text() );

	} else if ( event->key() == Qt::Key_Up && event->modifiers() == Qt::NoModifier ) {

		int index = p_itemList->currentRow() - 1;

		if ( index < 0 )
			index = p_itemList->count() - 1;

		setCurrentItem( selectedSection(), index );

	} else if ( ( event->key() == Qt::Key_Down && event->modifiers() == Qt::NoModifier ) ||
		( event->key() == Qt::Key_Tab && event->modifiers() == Qt::ControlModifier ) )
	{

		int index = p_itemList->currentRow() + 1;

		if ( index >= p_itemList->count() )
			index = 0;

		setCurrentItem( selectedSection(), index );

	} else if ( event->key() == Qt::Key_Escape && event->modifiers() == Qt::NoModifier )
		close();
	else if ( event->key() == Qt::Key_Return && event->modifiers() == Qt::NoModifier ) {

		emit_itemChanged( selectedSection(), selectedItemIndex() );

		close();

	} else
		QFrame::keyPressEvent(event);

}

void QyTabNavigator::keyReleaseEvent( QKeyEvent * event ) {

	if ( event->key() == Qt::Key_Control && !p_keepWindow ) {

		emit_itemChanged( selectedSection(), selectedItemIndex() );

		close();

	}

}

void QyTabNavigator::emit_itemChanged( const QString & section, int index ) {

	p_lastTrueIndex = index;
	p_lastTrueSection = section;

	emit itemChanged( section, index );

}
